import type { Next, Context } from 'koa';
import knex from '../utils/knex';
import { dataScopeHandler } from '../services/auth';
import md5 from 'md5';

/**
 * @api {get} /user/info 当前登录用户信息
 * @apiVersion 1.0.0
 * @apiDescription create by wuyanshen
 * @apiName info
 * @apiGroup 用户管理
 * @apiUse RequestHeader
 * @apiUse userInfoSuccess
 * @apiUse RequestError
 */
async function infoAction(ctx: Context, next: Next) {
    const userInfo = await knex('sys_user').where({ id: ctx.user.id }).first();
    ctx.success(userInfo);
    return next();
}

/**
 * @api {get} /user/retrieve 查询用户(分页)
 * @apiVersion 1.0.0
 * @apiDescription create by wuyanshen
 * @apiName retrieve
 * @apiGroup 用户管理
 *
 * @apiUse RequestPagingParam
 * @apiParam {String} username 用户名【非必填】
 * @apiParam {String} nickname 昵称【非必填】
 * @apiParam {String} phone 手机号【非必填】
 * @apiParam {String} startTime 创建时间-开始【非必填】
 * @apiParam {String} endTime 创建时间-结束【非必填】
 * @apiParam {int} org_id 部门id【非必填】
 * @apiParam {int} status 用户状态 (0:正常 1:停用)【非必填】
 *
 * @apiUse RequestHeader
 * @apiUse userRetrieveSuccess
 * @apiUse RequestError
 */
async function retrieveAction(ctx: Context, next: Next) {
    const page = (ctx.query.page || 1) as number;
    const size = (ctx.query.size || 10) as number;
    const username = ctx.query.username || '';
    const nickname = ctx.query.nickname || '';
    const phone = ctx.query.phone || '';
    const startTime = ctx.query.startTime || '';
    const endTime = ctx.query.endTime || '';
    const orgId = ctx.query.org_id;
    const status = ctx.query.status;
    const whereObj: Record<string, any> = {};
    if (orgId) {
        whereObj['u.org_id'] = orgId;
    }
    if (status) {
        whereObj['u.status'] = status;
    }
    if (username) {
        whereObj['u.username'] = ['like', `%${username}%`];
    }
    if (nickname) {
        whereObj['u.nickname'] = ['like', `%${nickname}%`];
    }
    if (phone) {
        whereObj['u.phone'] = phone;
    }
    if (startTime && endTime) {
        whereObj['u.create_time'] = ['between', startTime, endTime];
    }
    try {
        const dataScope = await dataScopeHandler(ctx.user.id || 0, 'u');
        const users = await knex({ u: 'sys_user' })
            .where(whereObj)
            // ====== 数据权限 start =======
            .leftJoin({ o: 'sys_org' }, 'o.id', 'u.org_id')
            .whereRaw(dataScope)
            .columns('u.*')
            // ====== 数据权限 end =======
            .offset((page - 1) * size)
            .limit(size)
            .select();
        const [count] = await knex({ u: 'sys_user' })
            .where(whereObj)
            // ====== 数据权限 start =======
            .leftJoin({ o: 'sys_org' }, 'o.id', 'u.org_id')
            .whereRaw(dataScope)
            .count();
        ctx.success(
            {
                data: users,
                count: Object.values(count)[0],
            },
            '查询成功',
        );
    } catch (e: any) {
        ctx.fail(500, e.toString());
    }
    return next();
}

/**
 * @api {post} /user/add 新增用户
 * @apiVersion 1.0.0
 * @apiDescription create by wuyanshen
 * @apiName add
 * @apiGroup 用户管理
 *
 * @apiParam {String} username 用户名【必填】
 * @apiParam {String} password 密码【必填】
 * @apiParam {String} nickname 昵称【必填】
 * @apiParam {String} phone 手机号【必填】
 * @apiParam {String} email 邮箱【必填】
 * @apiParam {String} avatar 头像【非必填】
 * @apiParam {int} org_id 部门id【必填】
 * @apiParam {int[]} roleIds 角色id集合【必填】
 * @apiParam {int} status 用户状态 (0:正常 1:停用)【必填】
 *
 * @apiUse RequestHeader
 * @apiUse addSuccess
 * @apiUse RequestError
 */
async function addAction(ctx: Context, next: Next) {
    const username = ctx.request.body.username;
    const nickname = ctx.request.body.nickname || '';
    const orgId = ctx.request.body.org_id || '';
    const phone = ctx.request.body.phone || '';
    const email = ctx.request.body.email || '';
    const avatar = ctx.request.body.avatar || 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif';
    const status = ctx.request.body.status || '';
    const roleIds = ctx.request.body.roleIds || [];
    const pwd = ctx.request.body.password || [];
    const password = md5(`${pwd}${username}`);

    try {
        await knex.transaction(function (trx) {
            // 新增用户
            knex('sys_user')
                .transacting(trx)
                .insert({
                    username: username,
                    password: password,
                    nickname: nickname,
                    org_id: orgId,
                    email: email,
                    avatar: avatar,
                    phone: phone,
                    status: status,
                })
                .then(async ([userId]) => {
                    // 删除user_role
                    await knex('sys_user_role').transacting(trx).where({ user_id: userId }).delete();
                    // 新增user_role
                    if (Array.isArray(roleIds) && roleIds.length > 0) {
                        const data = roleIds.map((roleId) => {
                            return {
                                user_id: userId,
                                role_id: roleId,
                            };
                        });
                        await knex.batchInsert('sys_user_role', data).transacting(trx);
                    }
                })
                .then(() => {
                    trx.commit();
                })
                .catch((err) => {
                    trx.rollback();
                    throw err;
                });
        });
        ctx.success('', '新增成功');
    } catch (e) {
        ctx.fail(500, '新增失败 ' + e);
    }
    return next();
}

/**
 * @api {put} /user/update 修改用户
 * @apiVersion 1.0.0
 * @apiDescription create by wuyanshen
 * @apiName update
 * @apiGroup 用户管理
 *
 * @apiParam {int} id 用户id【必填】
 * @apiParam {String} nickname 昵称【必填】
 * @apiParam {String} phone 手机号【必填】
 * @apiParam {String} email 邮箱【必填】
 * @apiParam {String} avatar 头像【非必填】
 * @apiParam {int} org_id 部门id【必填】
 * @apiParam {int[]} roleIds 角色id集合【必填】
 * @apiParam {int} status 用户状态 (0:正常 1:停用)【必填】
 *
 * @apiUse RequestHeader
 * @apiUse updateSuccess
 * @apiUse RequestError
 */
async function updateAction(ctx: Context, next: Next) {
    const id = ctx.request.body.id;
    const nickname = ctx.request.body.nickname || '';
    const orgId = ctx.request.body.org_id || '';
    const phone = ctx.request.body.phone || '';
    const email = ctx.request.body.email || '';
    // const avatar = this.post('avatar') || '';
    const status = ctx.request.body.status || '';
    const roleIds = ctx.request.body.roleIds || [];

    try {
        await knex.transaction(function (trx) {
            // 更新用户
            knex('sys_user')
                .transacting(trx)
                .where({ id: id })
                .update({
                    nickname: nickname,
                    org_id: orgId,
                    email: email,
                    // avatar: avatar,
                    phone: phone,
                    status: status,
                })
                .then(async () => {
                    // 删除user_role
                    await knex('sys_user_role').transacting(trx).where({ user_id: id }).delete();
                    // 新增user_role
                    if (Array.isArray(roleIds) && roleIds.length > 0) {
                        const data = roleIds.map((roleId) => {
                            return {
                                user_id: id,
                                role_id: roleId,
                            };
                        });
                        await knex.batchInsert('sys_user_role', data).transacting(trx);
                    }
                })
                .then(() => {
                    trx.commit();
                })
                .catch((err) => {
                    trx.rollback();
                    throw err;
                });
        });

        ctx.success('', '更新成功');
    } catch (e) {
        ctx.fail(500, '更新失败 ' + e);
    }
    return next();
}

/**
 * @api {delete} /user/delete 删除用户
 * @apiVersion 1.0.0
 * @apiDescription create by wuyanshen
 * @apiName delete
 * @apiGroup 用户管理
 *
 * @apiParam {int} id 用户id【必填】
 *
 * @apiUse RequestHeader
 * @apiUse deleteSuccess
 * @apiUse RequestError
 */
async function deleteAction(ctx: Context, next: Next) {
    const id = ctx.query.id;
    try {
        await knex.transaction(function (trx) {
            // 删除用户
            knex('sys_user')
                .transacting(trx)
                .where({ id: id })
                .delete()
                .then(async () => {
                    // 删除user_role
                    await knex('sys_user_role').transacting(trx).where({ user_id: id }).delete();
                })
                .then(() => {
                    trx.commit();
                })
                .catch((err) => {
                    trx.rollback();
                    throw err;
                });
        });
        ctx.success('', '删除成功');
    } catch (e) {
        ctx.fail(500, '删除失败 ' + e);
    }
    return next();
}

/**
 * @api {put} /user/updatePwd 个人中心修改密码
 * @apiVersion 1.0.0
 * @apiDescription create by wuyanshen
 * @apiName updatePwd
 * @apiGroup 用户管理
 *
 * @apiParam {int} id 用户id【必填】
 * @apiParam {String} username 用户名【必填】
 * @apiParam {String} password 密码【必填】
 *
 * @apiUse RequestHeader
 * @apiUse RequestSuccess
 * @apiUse RequestError
 */
async function updatePwdAction(ctx: Context, next: Next) {
    const id = ctx.request.body.id || ctx.user.id;
    const username = ctx.request.body.username || ctx.user.username;
    const password = ctx.request.body.password || '';
    const pwd = md5(`${password}${username}`);
    try {
        await knex('sys_user').where({ id: id }).update({
            password: pwd,
        });
        ctx.success('', '修改成功');
    } catch (e) {
        ctx.fail(500, '修改失败 ' + e);
    }
    return next();
}

/**
 * @api {put} /user/resetPwd 重置密码
 * @apiVersion 1.0.0
 * @apiDescription create by wuyanshen
 * @apiName resetPwd
 * @apiGroup 用户管理
 *
 * @apiParam {int} id 用户id【必填】
 * @apiParam {String} username 用户名【必填】
 * @apiParam {String} password 密码【必填】
 *
 * @apiUse RequestHeader
 * @apiUse RequestSuccess
 * @apiUse RequestError
 */
async function resetPwdAction(ctx: Context, next: Next) {
    const id = ctx.request.body.id;
    const username = ctx.request.body.username || '';
    const password = ctx.request.body.password || '';
    const pwd = md5(`${password}${username}`);
    try {
        await knex('sys_user').where({ id: id }).update({
            password: pwd,
        });
        ctx.success('', '修改成功');
    } catch (e) {
        ctx.fail(500, '修改失败 ' + e);
    }
    return next();
}

/**
 * @api {put} /user/profile 更新个人资料
 * @apiVersion 1.0.0
 * @apiDescription create by wuyanshen
 * @apiName profile
 * @apiGroup 用户管理
 *
 * @apiParam {int} id 用户id【必填】
 * @apiParam {String} nickname 用户名【必填】
 * @apiParam {String} phone 用户名【必填】
 * @apiParam {String} email 密码【必填】
 *
 * @apiUse RequestHeader
 * @apiUse RequestSuccess
 * @apiUse RequestError
 */
async function profileAction(ctx: Context, next: Next) {
    const id = ctx.request.body.id;
    const nickname = ctx.request.body.nickname || '';
    const phone = ctx.request.body.phone || '';
    const email = ctx.request.body.email || '';

    try {
        await knex('sys_user').where({ id: id }).update({
            nickname: nickname,
            email: email,
            phone: phone,
        });
        ctx.success('', '更新成功');
    } catch (e) {
        ctx.fail(500, '更新失败  ' + e);
    }
    return next();
}

/**
 * @api {get} /user/checkPwd 检查旧密码是否正确
 * @apiVersion 1.0.0
 * @apiDescription create by wuyanshen
 * @apiName checkPwd
 * @apiGroup 用户管理
 *
 * @apiParam {String} oldPassword 旧密码【必填】
 *
 * @apiUse RequestHeader
 * @apiUse checkPwdSuccess
 * @apiUse RequestError
 */
async function checkPwdAction(ctx: Context, next: Next) {
    const password = ctx.query.oldPassword;
    try {
        const userInfo = await knex('sys_user').where({ id: ctx.user.id }).first();
        if (md5(`${password}${ctx.user.username}`) === userInfo.password) {
            ctx.success(1, '旧密码正确');
        } else {
            ctx.success(0, '旧密码不正确');
        }
    } catch (e) {
        ctx.fail(500, '检查旧密码失败  ' + e);
    }
    return next();
}

/**
 * @api {put} /user/uploadAvatar 上传用户头像
 * @apiVersion 1.0.0
 * @apiDescription create by wuyanshen
 * @apiName uploadAvatar
 * @apiGroup 用户管理
 *
 * @apiParam {file} avatarfile 头像文件【必填】
 *
 * @apiUse RequestHeader
 * @apiUse checkPwdSuccess
 * @apiUse RequestError
 */
async function uploadAvatarAction(ctx: Context, next: Next) {
    const fileUrl = ctx.request.body.fileUrl;
    // 修改用户表的头像
    try {
        // 删除原来的头像
        // 更新用户头像
        await knex('sys_user').where({ id: ctx.user.id }).update({
            avatar: fileUrl,
        });
        ctx.success(fileUrl, '头像更新成功');
    } catch (e) {
        ctx.fail(500, '头像更新失败');
    }
    return next();
}

const userController = {
    infoAction,
    retrieveAction,
    addAction,
    updateAction,
    deleteAction,
    updatePwdAction,
    resetPwdAction,
    profileAction,
    checkPwdAction,
    uploadAvatarAction,
};

export default userController;
